package A0_Framework; /**
 * Created with IntelliJ IDEA.
 * User: Semen.Pleshivtsev
 * Date: 18.01.13
 * Time: 16:27
 * To change this template use File | Settings | File Templates.
 */

import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.Select;

import java.util.concurrent.TimeUnit;
import static java.lang.System.currentTimeMillis;
import static org.testng.Assert.assertTrue;

public class FrameWork {

    private WebDriver driver;  // Драйвер selenium
    private String baseUrl;    // начальная страница
    private StringBuffer verificationErrors = new StringBuffer(); // ???
    //    --
    private String UrlState; // Хранение текущего положения браузера

    public FrameWork(WebDriver drv, String b_url)
    {
        driver = drv;
        baseUrl = b_url;
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        UrlState = baseUrl;

    }// public void Framework()


//***********************************************
// Последние изменения:
/*  14.12.2012 (Семен Плешивцев)
В фреймворк добавлен метод CheckForText_Std1_Source
Значительно ускорена работа метода CheckForText_Std1
*/
//***********************************************


//***************************************************************************************************
//***************************************************************************************************
//*** Framework ***
// CheckForTextPresent (String str) - проверка на наличие текста на странице
// CheckForTextNotPresent (String str) - проверка на отсутствие текста на странице
// CheckForText_Std1 (String str) - проверка на отсутствие стандартных ошибок и наличие строки в тексте
//   -- CheckForText_Std1 (String str, String str2) - проверка на отсутствие стандартных ошибок и наличие двух в тексте
// CheckForText_Std1_Source (String str) - Проверка на текст в исходном коде документа. Может испольоваться, когда возвращается xml документ
// User_Site_Login(String login, String pass) - Логин пользователя на сайт
// Get_UrlState() - Запись текущей страницы
// Set_UrlState() - Переход на сохраненную страницу
// -------------------------------------

    // Функция проверки на наличие строки в тексте
    // Входные параметры:
    //      str - Строка наличие которой проверяется текст документа
    //---------------------------------------------
    // Автор: Семен Плешивцев; 10.12.2012
    // Изменения: Семен Плешивцев; 10.12.2012
    // В настоящий момент
    private boolean Frwk_CheckForTextPresent (String str)
    {
        try
        {
            return(driver.findElement(By.cssSelector("BODY")).getText().matches(str));
        } catch (Error e) {
            verificationErrors.append(e.toString());
            return (false);
        } // try - catch

    }// private boolean Frwk_CheckForTextPresent (String str

    // Функция проверки на отсутствие строки в тексте
    // Входные параметры:
    //      str - Строка отстутствие которой проверяется текст документа
    //---------------------------------------------
    // Автор: Семен Плешивцев; 11.12.2012
    // Изменения: Семен Плешивцев; 11.12.2012
    public boolean CheckForTextNotPresent (String str)
    {
        try
        {
            return(!driver.findElement(By.cssSelector("BODY")).getText().matches(str));

        } catch (Error e) {
            verificationErrors.append(e.toString());
            return (true);
        } // try - catch

    }// private boolean Frwk_CheckForTextNotPresent (String str)

    // Функция проверки на отсутствие стандартных строк в тексте и наличие заданной по маске
    // Входные параметры:
    //      str - Строка наличие которой проверяется текст документа
    //---------------------------------------------
    // Автор: Семен Плешивцев; 11.12.2012
    // Изменения: Семен Плешивцев; 14.12.2012
    //  - Использована переменная DocumentText вместо вызова метода CheckForTextNotPresent
    public boolean CheckForText_Std1 (String str)
    {
        String DocumentText;
        try
        {
            DocumentText = driver.findElement(By.cssSelector("BODY")).getText();
            return(
                    !DocumentText.matches("^[\\s\\S]*Exception[\\s\\S]*$") &
                            !DocumentText.matches("^[\\s\\S]*Nephrite.[\\s\\S]*$") &
                            !DocumentText.matches("^[\\s\\S]*сервер не может обработать ваш запрос[\\s\\S]*$") &
                            DocumentText.matches(str)
            );


        } catch (Error e) {
            verificationErrors.append(e.toString());
            return (false);
        } // try - catch

    }// private boolean Frwk_CheckForText_Std1 (String str)

    // Перегрузка функции, проверка на наличие двух строк по маске
    // Автор: Семен Плешивцев; 12.12.2012
    // Изменения: Семен Плешивцев; 14.12.2012
    //  - Использована переменная DocumentText вместо вызова метода CheckForTextNotPresent
    public  boolean CheckForText_Std1 (String str, String str2)
    {
        String DocumentText;
        try
        {
            DocumentText = driver.findElement(By.cssSelector("BODY")).getText();
            return(
                    !DocumentText.matches("^[\\s\\S]*Exception[\\s\\S]*$") &
                            !DocumentText.matches("^[\\s\\S]*Nephrite.[\\s\\S]*$") &
                            !DocumentText.matches("^[\\s\\S]*сервер не может обработать ваш запрос[\\s\\S]*$") &
                            DocumentText.matches(str) &
                            DocumentText.matches(str2)
            );

        } catch (Error e) {
            verificationErrors.append(e.toString());
            return (false);
        } // try - catch

    }// private boolean CheckForText_Std1 (String str, String str2)

    // Функция проверки на отсутствие стандартных строк в тексте и наличие заданной (точное соответствие)
    // Входные параметры:
    //      str - Строка наличие которой проверяется текст документа
    //---------------------------------------------
    // Автор: Семен Плешивцев; 22.01.2013
    // Изменения: Семен Плешивцев; 22.01.2013
    public boolean CheckForText_Std1_Exact (String str)
    {
        String DocumentText;
        try
        {
            DocumentText = driver.findElement(By.cssSelector("BODY")).getText();
            return(
                    !DocumentText.matches("^[\\s\\S]*Exception[\\s\\S]*$") &
                            !DocumentText.matches("^[\\s\\S]*Nephrite.[\\s\\S]*$") &
                            !DocumentText.matches("^[\\s\\S]*сервер не может обработать ваш запрос[\\s\\S]*$") &
                            DocumentText.contains(str)
            );

        } catch (Error e) {
            verificationErrors.append(e.toString());
            return (false);
        } // try - catch
    }// public boolean CheckForText_Std1_Exact (String str)

    // Функция проверки на отсутствие стандартных строк в тексте и наличие заданной (точное соответствие, две строки)
    public boolean CheckForText_Std1_Exact (String str, String str2)
    {
        String DocumentText;
        try
        {
            DocumentText = driver.findElement(By.cssSelector("BODY")).getText();
            return(
                    !DocumentText.contains("Exception") &
                            !DocumentText.contains("Nephrite.") &
                            !DocumentText.contains("сервер не может обработать ваш запрос") &
                            DocumentText.contains(str) &
                            DocumentText.contains(str2)
            );

        } catch (Error e) {
            verificationErrors.append(e.toString());
            return (false);
        } // try - catch
    }// public boolean CheckForText_Std1_Exact (String str, String str2)

    // Функция проверки на отсутствие стандартной строки в тексте и наличие заданной в исходном коде документа
    // Входные параметры:
    //      str - Строка наличие которой проверяется текст документа
    //---------------------------------------------
    // Автор: Семен Плешивцев; 14.12.2012
    // Изменения: Семен Плешивцев; 14.12.2012
    public boolean CheckForText_Std1_Source (String str)
    {
        String pagesource;
        try
        {
            pagesource = driver.getPageSource();
            return(
                    !pagesource.matches("^[\\s\\S]*Exception[\\s\\S]*$") &
                            !pagesource.matches("^[\\s\\S]*Nephrite.[\\s\\S]*$") &
                            !pagesource.matches("^[\\s\\S]*сервер не может обработать ваш запрос[\\s\\S]*$") &
                            pagesource.matches(str));
        } catch (Error e) {
            verificationErrors.append(e.toString());
            return (false);
        } // try - catch

    }// private boolean CheckForText_Std1_Source (String str)


    // Функция проверки на отсутствие стандартной строки в тексте и наличие заданной в исходном коде документа
    // Входные параметры:
    //      str - Строка наличие которой проверяется текст документа
    //---------------------------------------------
    // Автор: Семен Плешивцев; 17.12.2012
    // Изменения: Семен Плешивцев; 17.12.2012
    public void User_Site_Login(String login, String pass)
    {
        driver.get(baseUrl + "/");
        // Авторизация пользователя
        driver.findElement(By.linkText("Вход")).click();

        driver.findElement(By.id("ctl12_ctl08_ctl00_btnOK")).click();
        driver.findElement(By.id("ctl12_ctl08_ctl00_tbLogin")).clear();
        driver.findElement(By.id("ctl12_ctl08_ctl00_tbLogin")).sendKeys(login);
        driver.findElement(By.id("ctl12_ctl08_ctl00_tbPassword")).clear();
        driver.findElement(By.id("ctl12_ctl08_ctl00_tbPassword")).sendKeys(pass);
        driver.findElement(By.id("ctl12_ctl08_ctl00_bOK")).click();

    }// User_Site_Login(String login, String pass)

    // Функция сохранения текущей открытой страницы
    // Входные параметры: нет
    //---------------------------------------------
    // Автор: Семен Плешивцев; 20.12.2012
    // Изменения: Семен Плешивцев; 20.12.2012
    public void Get_UrlState()
    {
        UrlState = driver.getCurrentUrl();
    } //private boolean Get_CurrentUrl_State()

    // Функция перехода к сохраненному положению браузера
    // Входные параметры: нет
    //---------------------------------------------
    // Автор: Семен Плешивцев; 20.12.2012
    // Изменения: Семен Плешивцев; 20.12.2012

    public void Set_UrlState()
    {
        driver.get(UrlState);
    } //private boolean Get_CurrentUrl_State()

    // Функция ожидания текста на странице
    // Входные параметры:
    //     String str - текст, который ожидаем  на странице
    //     Integer TimeOut - время ожидания в секундах
    //---------------------------------------------
    // Автор: Семен Плешивцев; 21.12.2012
    // Изменения: Семен Плешивцев; 21.12.2012
    public boolean WaitForTextPresent(String str, Integer TimeOut)
    {
        Boolean TextFound;
        Long start,end;

        start = currentTimeMillis();
        end = start;

        try
        {
            TextFound = driver.getPageSource().contains(str);
            while((!TextFound) & (( (end - start)/1000 ) < TimeOut))
            {
                TextFound = driver.getPageSource().contains(str);
                end = currentTimeMillis();

            }//while((!TextFound) & ((end - start)/1000) < TimeOut))

            if (TextFound)
            {
                return(true);
            }// if
            else return(false);
        }// try
        catch (Error e)
        {
            return(false);
        } // try - catch
    }// private boolean WaitForTextPresent(String str, Integer TimeOut)

    // Функция которая ожидает, пока текст пропадет со страницы в течении заданного времени
    // Входные параметры:
    //     String str - текст, который ожидаем  на странице
    //     Integer TimeOut - время ожидания в секундах
    //---------------------------------------------
    // Автор: Семен Плешивцев; 21.02.2013
    // Изменения: Семен Плешивцев; 21.02.2013
    public void WaitForTextNotPresent(String str, Integer TimeOut)
    {
        Boolean TextFound;
        Long start,end;

        start = currentTimeMillis();
        end = start;

        try
        {
            TextFound = driver.getPageSource().contains(str);
            while((TextFound) & (( (end - start)/1000 ) < TimeOut))
            {
                TextFound = driver.getPageSource().contains(str);
                end = currentTimeMillis();
            }//while((TextFound) & ((end - start)/1000) < TimeOut))

        }// try
        catch (Error e)
        {
            // hmmm ?
        } // try - catch
    }// public boolean WaitForTextNotPresent(String str, Integer TimeOut)

    // Функция выбора из выпадающего списка, если элемент склонен вываливаться в "org.openqa.selenium.StaleElementReferenceException: Element is no longer attached to the DOM"
    // Пытается выбрать из списка в течение указанного времени
    // Входные параметры:
    //     Element_Id - ID элемента
    //     Select_Option - элемент списка
    //     TimeOut - время ожидания в секундах
    //---------------------------------------------
    // Автор: Семен Плешивцев; 30.01.2013
    // Изменения: Семен Плешивцев; 30.01.2013
    public boolean Select_byID_Stale_Exception(String Element_Id, String Select_Option, Integer TimeOut)
    {
        Boolean OptionSelected = false;
        Long start,end;

        start = currentTimeMillis();
        end = start;

        if (TimeOut <= 0) return false;

        while (!OptionSelected & (( (end - start)/1000 ) < TimeOut))
        {
            end = currentTimeMillis();
            try
            {
                new Select(driver.findElement(By.id(Element_Id))).selectByVisibleText(Select_Option);
                OptionSelected = true;
            }
            catch (StaleElementReferenceException e)
            {
                OptionSelected = false;
            } // try - catch
        }// while (!OptionSelected & (( (end - start)/1000 ) < TimeOut))
        return OptionSelected;
    }//public boolean Select_byID_Stale_Exception()

    // Пауза выполнения на необходимое количество секунд
    // Входные параметры:
    //     Sec - Сколько секунд ждать
    //---------------------------------------------
    // Автор: Семен Плешивцев; 05.02.2013
    // Изменения: Семен Плешивцев; 05.02.2013
    public void Sleep(Integer sec)
    {
        try {
            Thread.sleep(sec*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }// public void Sleep(Integer sec)


    // Прогресс бар в текстовом поле формы
    // Ожидает заданное количество времени и выводит оставшееся время в текстовое поле
    // Если время ожидания задано меньше 10 секунд, то принудительно устанавливает время ожидания равным 10 секундам
    // Входные параметры:
    //   Sec - Сколько секунд ждать
    //   Field_Id - ID поля, в которое выводим сообщение
    //---------------------------------------------
    // Автор: Плешивцев Семен; 05.03.2013
    // Изменения: Плешивцев Семен; 05.03.2013
    public void Progress_Txt(Integer Sec,String Field_ID)
    {
        Integer Count_Down;

        if (Sec < 10) Sec = 10;  // Устанавливаем счетчик на разумное время (10 секунд минимум)
        Count_Down = Sec;

        while (Count_Down > 0)
        {
            driver.findElement(By.id(Field_ID)).clear();
            driver.findElement(By.id(Field_ID)).sendKeys("Осталось "+ Count_Down + " секунд");
            Sleep(10);
            Count_Down -= 10;
        }//while (Count_Down > 0)

    }//public void Progress_Txt()

    // Поиск объекта через поле быстрого поиска, ожидание объекта в реестре, и после появления, клик на верхнюю ссылку.
    //
    // Входные параметры:
    //   Wait_Max - Максимальный период ожидания в секундах
    //   Wait_Period - Периодичность проверки
    //   Object_Str - строка, по которой ищем объект
    //---------------------------------------------
    // Автор: Плешивцев Семен; 05.03.2013
    // Изменения: Плешивцев Семен; 05.03.2013
    public void Search_Wait_And_Click(Integer Wait_Max, Integer Wait_Period,String Object_Str)
    {
        Integer Count_Down;  // Обратный отсчет ожидания
        Boolean Object_Found; // Флаг "Объект найден"
        String Page_Source; // Исходник страницы
        Integer Render_Time = 5; // Количество времени, необходимое на отрисовку страницы после поиска

        if (Wait_Max < 10) Wait_Max = 10;  // Устанавливаем счетчик на разумное время (10 секунд минимум)
        if (Wait_Period < 5) Wait_Period = 5; //// Устанавливаем период ожидания на разумное время (11 секунда минимум)

        Count_Down = Wait_Max;

        driver.findElement(By.id("qfind")).clear();
        driver.findElement(By.id("qfind")).sendKeys(Object_Str);
        Sleep(Render_Time);

        Page_Source = driver.getPageSource();
        Object_Found = !Page_Source.contains("<b>Всего записей:</b> 0");

        Integer i = 2;
        while ((Count_Down > 0) & (!Object_Found))
        {
            driver.findElement(By.id("qfind")).clear();
            driver.findElement(By.id("qfind")).sendKeys("Повторная попытка через "+Wait_Period +" секунд");
            Sleep(Wait_Period);
            Count_Down -= Wait_Period - Render_Time;

            driver.findElement(By.id("qfind")).clear();
            driver.findElement(By.id("qfind")).sendKeys(Object_Str);
            Sleep(Render_Time);

            Page_Source = driver.getPageSource();
            Object_Found = !Page_Source.contains("<b>Всего записей:</b> 0");
        }//while ((Count_Down > 0) & (!Object_Found))

        if (Object_Found)
        {
            Sleep(1);
            driver.findElement(By.xpath("//div[@id='Workspace1_ctl01_up']/table/tbody/tr[2]/td/a")).click();
        }// if (Object_Found)

    }//public void Search_Wait_And_Click(Integer Wait_Max, Integer Wait_Period,String Object_Str)

    // Стандартная сортировка реестра.
    // Функция проверяет сортировку по заданному количеству столбцов реестра и подтверждает наличие указанных строк
    // в тексте страницы. Дополнительно подтверждает отстуствие стандартных ошибок.
    // Если заданное количество столбцов < 1, то принудительно проверяется сортировка по первому столбцу реестра
    //
    // Входные параметры:
    //     col_num - количество проверяемых столбцов
    //     str1, str2 - проверяемые строки
    //---------------------------------------------
    // Автор: Семен Плешивцев; 21.02.2013
    // Изменения: Семен Плешивцев; 21.02.2013
    public void Sorting (Integer col_num, String str1, String str2)
    {
        String Column_Path;  // xpath до столбца

        if (col_num < 1) col_num = 1;
        Column_Path = "//th/table/tbody/tr/td/a";

        for (int i=1; i<= col_num; i++)
        {
            if (i > 1) Column_Path = "//th[" + i + "]/table/tbody/tr/td/a"; // Формирую xpath до заголовка столбца
            driver.findElement(By.xpath(Column_Path)).click(); // Сортировка по возрастанию
            // Sleep(1);
            assertTrue((CheckForText_Std1_Exact(str1,str2)),"Fail sorting by column(acs.) #"+i);

            driver.findElement(By.xpath(Column_Path)).click(); // Сортировка по убыванию
            // Sleep(1);
            assertTrue((CheckForText_Std1_Exact(str1,str2)),"Fail sorting by column(decs.) #"+i);
        }// for (int i=1; i<= col_num; i++)

    }//public void Sort_FirstColumn_Std1 (String str)

    // Стандартная фильтрация реестра.
    // Проверяет на работоспособность функции фильтра при условии, что параметр и значения фильтра
    // выбираются из выпадающего списка.
    // После применения фильтра проверяет на наличие заданных строк и отсутствие стандартных ошибок
    //
    // Входные параметры:
    //     Filter_Param - Параметр фильтра
    //     Filter_Value - Значение параметра
    //     str1, str2 - проверяемые строки
    //---------------------------------------------
    // Автор: Семен Плешивцев; 21.02.2013
    // Изменения: Семен Плешивцев; 21.02.2013
    public void Filter_Select (String Filter_Param, String Filter_Value, String str1, String str2)
    {
        String Parameter_Selector;  // Селектор параметра фильтра
        String Value_Selector;      // Селектор значения параметра

        Parameter_Selector ="option[value=\"" + Filter_Param + "\"]";
        Value_Selector = "Workspace1_ctl01_filter_filter_tcFilter_tp1_ddlValue";

        driver.findElement(By.xpath("(//a[contains(text(),'Фильтр')])[2]")).click(); // Нажать на кнопку Фильтр
        WaitForTextPresent("Расширенный фильтр",15);
        Sleep(2);
        assertTrue((CheckForText_Std1_Exact("Расширенный фильтр")),"Fail when opening filter window"); // Проверка на то, что окно фильтра открылось

        driver.findElement(By.cssSelector(Parameter_Selector)).click();                             // Выбор параметра по которому фильтруем
        Sleep(2);
        new Select(driver.findElement(By.id(Value_Selector))).selectByVisibleText(Filter_Value);    // Выбор значения параметра
        Sleep(2);

        driver.findElement(By.id("Workspace1_ctl01_filter_filter_tcFilter_tp1_addItem")).click();   // Нажать на кнопку добавления критерия
        WaitForTextPresent(Filter_Param + " = \"" + Filter_Value + "\"",10);

        driver.findElement(By.id("Workspace1_ctl01_filter_filter_btnOK")).click(); // Нажать на кнопку ОК
        Sleep(2);

        assertTrue((CheckForText_Std1_Exact(str1,str2)),"Fail after applying filter");

    }// public void Filter_Select (String Filter_Param, String Filter_Value, String str1, String str2)


    // Стандартная фильтрация реестра.
    // Проверяет на работоспособность функции фильтра при условии, что параметр и условие фильтра
    // выбираются из выпадающего списка. Значение параметра вводится как текст
    // После применения фильтра проверяет на наличие заданных строк и отсутствие стандартных ошибок
    //
    // Входные параметры:
    //     Filter_Param - Параметр фильтра
    //     Filter_Condition - Условие
    //     Filter_Value - Значение параметра
    //     str1, str2 - проверяемые строки
    //---------------------------------------------
    // Автор: Семен Плешивцев; 21.02.2013
    // Изменения: Семен Плешивцев; 21.02.2013
    public void Filter_Type (String Filter_Param, String Filter_Condition, String Filter_Value, String str1, String str2)
    {
        String Condition_Selector; // Селектор условия

        Condition_Selector = "option[value=\"" + Filter_Condition + "\"]";

        driver.findElement(By.xpath("(//a[contains(text(),'Фильтр')])[2]")).click(); // Нажать на кнопку Фильтр
        WaitForTextPresent("Расширенный фильтр",15);
        Sleep(2);
        assertTrue((CheckForText_Std1_Exact("Расширенный фильтр")),"Fail when opening filter window"); // Проверка на то, что окно фильтра открылось

        new Select(driver.findElement(By.xpath("//select"))).selectByVisibleText(Filter_Param);                             // Выбор параметра по которому фильтруем
        Sleep(2);

        new Select(driver.findElement(By.id("Workspace1_ctl01_filter_filter_tcFilter_tp1_ddlCondition"))).selectByVisibleText(Filter_Condition); //Выбор условия
        Sleep(2);

        driver.findElement(By.id("Workspace1_ctl01_filter_filter_tcFilter_tp1_txtValue")).sendKeys(Filter_Value);  // Выбор значения параметра
        Sleep(2);


        driver.findElement(By.id("Workspace1_ctl01_filter_filter_tcFilter_tp1_addItem")).click();   // Нажать на кнопку добавления критерия
        WaitForTextPresent(Filter_Param + " = \"" + Filter_Value + "\"",10);

        driver.findElement(By.id("Workspace1_ctl01_filter_filter_btnOK")).click(); // Нажать на кнопку ОК
        Sleep(2);

        assertTrue((CheckForText_Std1_Exact(str1,str2)),"Fail after applying filter");

    }// public void Filter_Select (String Filter_Param, String Filter_Value, String str1, String str2)



    // Проверка карточки реестра.
    // Открывает верхнюю карточку реестра и проверяет на наличие указанных строк и отсутствие стандартных ошибок
    //
    // Входные параметры:
    //     str1, str2 - проверяемые строки
    //---------------------------------------------
    // Автор: Семен Плешивцев; 21.02.2013
    // Изменения: Семен Плешивцев; 21.02.2013
    public void Top_Card (String str1, String str2)
    {
        String Card_Selector;  // Селектор параметра фильтра

        Card_Selector = "//div[@id='Workspace1_ctl01_up']/table/tbody/tr[2]/td/a"; // Верхняя строчка в списке значения

        driver.findElement(By.xpath(Card_Selector)).click();
        assertTrue((CheckForText_Std1_Exact(str1,str2)),"Card view fail");

    }// public void Top_Card (String str1, String str2)



//***************************************************************************************************
//***************************************************************************************************
//*** End of Framework ***


}// public class Framework